from apps.pay.recordIncomes.baseViews import *
from apps.system.user.dao import UserDao
from django.db.models import Sum
from decimal import Decimal
from apps.pay.recordIncomes.dao import RecordIncomesDao
from apps.system.lessee.dao import LesseeDao
from apps.system.payway.dao import PaywayDao
from apps.common.utils.time import getFormatTime
from apps.pay.recordIncomes.functions import autoFreeBalanceLockedRecord, freeBalanceLockedRecord, freePoolMonth
from apps.pay.recordIncomes.service_exportExcel import exportExcel
from apps.pay.recordIncomes.service_exportExcelForShop import exportExcelForShop
from django.http import FileResponse



def getAllRecordIncomes():
    _list = RecordIncomesDao().findAll().select_related('user', 'shop','fromUser', 'payWayAccount')
    return _list

class RecordIncomesForShopOutMoneyViewSet(BaseRecordIncomesViewSet):

    def get_queryset(self):
        params = getRequestParams(self.request)
        _list = getAllRecordIncomes().filter(Q(scene='outMoney')|Q(scene='onlineSettle')|Q(scene='shopinSettle'), shop__isnull=False)
        if params.get('routerName') == 'shopSettle':  # 加盟店结算
            if BaseDao().findRoleByAccount(self.request.user).key == '加盟店':
                _list = _list.filter(Q(shop__types='1'), shop__admin=self.request.user)
            elif BaseDao().findRoleByAccount(self.request.user).key == 'custom':
                _list = _list.filter(shop__user=self.request.user)
            else:
                _list = _list
        elif params.get('routerName') == 'supplierSettle': # 供应商结算
            if BaseDao().findRoleByAccount(self.request.user).key == '供应链':
                _list = _list.filter(Q(shop__types='0')) 
            else:
                _list = _list
        return _list
    @action(methods=['post'], detail=False)
    def exportExcel(self, request):
        params = getRequestParams(request)
        _orders = getAllRecordIncomes().filter(scene='outMoney', shop__isnull=False)
        # 如果是根据筛选条件导出
        if params.get('routerName') == 'shopSettle':  # 加盟店结算
            _orders = _orders.filter(Q(shop__types='1'))
        elif params.get('routerName') == 'supplierSettle': # 供应商结算
            _orders = _orders.filter(Q(shop__types='3'))
        # 如果是选择导出
        if type(params.get('ids')) == list and len(params.get('ids'))>0:
            _orders = _orders.filter(id__in=params.get('ids'))
            output = exportExcelForShop(_orders)
            return FileResponse(output, as_attachment=True)
        
        # 查询出要导出的数据
        query_params = {}
        exclude_params = {}
        if params.get('orderId'):
            query_params['orderId'] = params.get('orderId')
        if params.get('user'):
            query_params['user'] = params.get('user')
        if params.get('orderStatus'):
            query_params['orderStatus'] = params.get('orderStatus')
        query_params['createTime__gte'] = params.get('startTime') if params.get(
            'startTime') else datetime.datetime.now() - datetime.timedelta(days=30)
        query_params['createTime__lte'] = params.get('endTime') if params.get(
            'endTime') else datetime.datetime.now() + datetime.timedelta(days=1)

        _orders = _orders.filter(**query_params).exclude(**exclude_params)
        output = exportExcelForShop(_orders)
        return FileResponse(output, as_attachment=True)

class RecordIncomesForOutMoneyViewSet(BaseRecordIncomesViewSet):

    def get_queryset(self):
        params = getRequestParams(self.request)
        _list = getAllRecordIncomes().filter(scene='outMoney', user__isnull=False)
        return _list
    @action(methods=['post'], detail=False)
    def exportExcel(self, request):
        params = getRequestParams(request)
        _orders = getAllRecordIncomes().filter(scene='outMoney', user__isnull=False)
        if type(params.get('ids')) == list and len(params.get('ids'))>0:
            _orders = _orders.filter(id__in=params.get('ids'))
            output = exportExcel(_orders)
            return FileResponse(output, as_attachment=True)
        
        # 查询出要导出的数据
        query_params = {}
        exclude_params = {}
        if params.get('orderId'):
            query_params['orderId'] = params.get('orderId')
        if params.get('user'):
            query_params['user'] = params.get('user')
        if params.get('orderStatus'):
            query_params['orderStatus'] = params.get('orderStatus')
        query_params['createTime__gte'] = params.get('startTime') if params.get(
            'startTime') else datetime.datetime.now() - datetime.timedelta(days=30)
        query_params['createTime__lte'] = params.get('endTime') if params.get(
            'endTime') else datetime.datetime.now() + datetime.timedelta(days=1)

        _orders = _orders.filter(**query_params).exclude(**exclude_params)
        output = exportExcel(_orders)
        return FileResponse(output, as_attachment=True)
    
    
class RecordIncomesLockedViewSet(BaseRecordIncomesViewSet):

    def get_queryset(self):
        params = getRequestParams(self.request)
        _list = getAllRecordIncomes().filter(payway='incomesLocked', changeWay='add')
        return _list

class RecordIncomesViewSet(BaseRecordIncomesViewSet):

    def get_queryset(self):
        params = getRequestParams(self.request)
        _list = getAllRecordIncomes()
        if params.get('createTimeValue'):
            date_obj = datetime.datetime.strptime(params.get('createTimeValue'), '%Y-%m-%d').date()
            _list = _list.filter(createTime__date=date_obj)
        return _list

    '''当日余额总计'''
    @action(methods=['post'], detail=False)
    def shopBalanceTotal(self, request):
        params = getRequestParams(self.request)
        _list = getAllRecordIncomes().filter(payway=params.get('payway'), shop=params.get('shop'))
        if params.get('createTimeValue'):
            date_obj = datetime.datetime.strptime(params.get('createTimeValue'), '%Y-%m-%d').date()
            _list = _list.filter(createTime__date=date_obj)
        shopBalanceTotal = _list.aggregate(sums=Sum('money'))['sums'] or 0
        return Response(response_success({'shopBalanceTotal': str(shopBalanceTotal)}))

    '''我的钱包'''
    @action(methods=['post'], detail=False)
    def myWallet(self, request):
        incomesLocked = RecordIncomesDao().findAll().filter(payway='incomesLocked', changeWay='add', moneyLocked__gt=0, user=request.user).aggregate(sums=Sum('moneyLocked'))['sums'] or 0
        # 贡献值
        contributionValue = RecordIncomesDao().findAll().filter(payway='contributionValue', changeWay='add', money__gt=0, user=request.user).aggregate(sums=Sum('money'))['sums'] or 0
        # 提现中
        outMoneying = RecordIncomesDao().findAll().filter(user=request.user, payway='incomes', scene='outMoney', orderStatus='WAIT_SEND').aggregate(sums=Sum('money'))['sums'] or 0
        # 累计提现
        historyOutMoney = RecordIncomesDao().findAll().filter(user=request.user, payway='balance', scene='outMoney', orderStatus='FINISH').aggregate(sums=Sum('money'))['sums'] or 0
        return Response(response_success({
            "incomes": str(request.user.incomes),# 积分余额
            "incomesLocked": str(incomesLocked),# 锁定积分
            "balance": str(request.user.balance),# 现金余额
            "incomesCredit": str(request.user.incomesCredit), # 抵扣积分
            "contributionValue": str(contributionValue), # 贡献值
            "incomesOriginal": str(request.user.incomesOriginal), # 原积分
            "historyIncomes": str(request.user.historyIncomes),#历史累计收益
            "outMoneying": str(outMoneying),
            "historyOutMoney": str(historyOutMoney)
        }))
    

    '''手动释放'''
    @action(methods=['post'], detail=False)
    def freeBalanceLockedRecordApi(self, request):
        params = getRequestParams(request)
        lessee = LesseeDao().getLessee()
        freeMoney = params.get('freeMoney')
        cycle = params.get('cycle')
        if not freeMoney:
            return Response(response_message('请输入释放金额'))
        if Decimal(freeMoney) > lessee.freePoolDay:
            return Response(response_message('释放金额不能大于日释放池'))
        date = datetime.datetime.now().strftime('%Y-%m-%d')
        freeBalanceLockedRecord(date, freeMoney)
        # autoFreeBalanceLockedRecord()
        return Response(response_success("操作成功"))
    
    @action(methods=['post'], detail=False)
    def freePoolMonthApi(self, request):
        params = getRequestParams(request)
        lessee = LesseeDao().getLessee()
        freeMoney = params.get('freeMoney')
        cycle = params.get('cycle')
        if not freeMoney:
            return Response(response_message('请输入释放金额'))
        if Decimal(freeMoney) > lessee.freePoolMonth:
            return Response(response_message('释放金额不能大于月释放池'))
        freePoolMonth(cycle, freeMoney)
        return Response(response_success("操作成功"))

    '''用户提现'''
    @action(methods=['post'], detail=False)
    def outMoneyForUser(self, request):
        params = getRequestParams(request)
        _lessee = LesseeDao().getLessee()
        userMoney = 0
        if request.user.isRobot:
            return Response(response_message('机器人账户不能提现'))
        paywayType = params.get('paywayType')
        if not paywayType:
            return Response(response_message('请选择提现方式'))
        if paywayType == 'balance':
            userMoney = request.user.balance
        elif paywayType == 'incomes':
            userMoney = request.user.incomes
        else:
            return Response(response_message('请选择提现方式'))
        
        if not params.get('payWayId'):
            return Response(response_message("请选择收款账户！"))
        elif Decimal(userMoney) < Decimal(params.get('payMoney')):
            return Response(response_message("提现失败！余额不足！"))
        elif Decimal(params.get('payMoney')) < _lessee.serviceCharge_min:
            return Response(response_message("提现失败！最小提现金额"+str(_lessee.serviceCharge_min)+"元！"))
        elif Decimal(params.get('payMoney')) > _lessee.serviceCharge_max:
            return Response(response_message("提现失败！最大提现金额"+str(_lessee.serviceCharge_max)+"元！"))
        elif RecordIncomesDao().findAll().filter(user=request.user, scene='outMoney', payway=paywayType, createTime__date=datetime.datetime.now()).count()>=_lessee.serviceChargeNum:
            return Response(response_message("每日最多只能发起"+str(_lessee.serviceChargeNum)+"次提现！"))
        else:
            payMoney = Decimal(params.get('payMoney')).quantize(Decimal('0.00'))
            # 减少用户余额
            UserDao().subWallet(paywayType, request.user, payMoney)
            # 计算实际到账
            serviceChargeRate = _lessee.serviceChargeRate
            serviceCharge = 0
            if serviceChargeRate > 0:
                serviceCharge = (payMoney * serviceChargeRate).quantize(Decimal('0.00'))
            realPay = payMoney - serviceCharge
            # 提现账号信息
            payWayAccount = PaywayDao().findOneByObjId(params.get('payWayId'))
            receiptAccount = json.dumps({"types":payWayAccount.types,"paywayCodeUrl":payWayAccount.paywayCodeUrl,"creditedName": payWayAccount.realname, "creditedBank": payWayAccount.accountName, "creditedAccount": payWayAccount.account, "bankCode": payWayAccount.bankCode})
            data = {}
            data['scene'] = 'outMoney'
            data['payWayAccount'] = params.get('payWayId')
            data['receiptAccount'] = receiptAccount
            data['user'] = request.user.id
            data['fromUser'] = request.user.id
            data['orderId'] = getFormatTime('%Y%m%d%H%M%S') + random_num(8)
            data['money'] = payMoney
            data['serviceCharge'] = serviceCharge
            data['realMoney'] = realPay
            data['payway'] = paywayType
            data['changeWay'] = 'sub'
            data['orderStatus'] = 'WAIT_SEND'
            RecordIncomesDao().create(data)

        return Response(response_success("操作成功"))

    '''提现确认'''
    @action(methods=['post'], detail=False)
    def confirmOutMoney(self, request):
        params = getRequestParams(request)
        order = RecordIncomesDao().findOneByObjId(params.get('obj_id'))
        if order.orderStatus != 'WAIT_SEND':
            return Response(response_message("待打款的订单才允许处理！"))
        order.__dict__.update({'orderStatus': 'FINISH', 'remark': params.get('remark'), 'outMoneyTime': datetime.datetime.now()})
        order.save()

        return Response(response_success("操作成功"))

    '''提现拒绝'''
    @action(methods=['post'], detail=False)
    def refuseOutMoney(self, request):
        params = getRequestParams(request)
        paywayType = params.get('paywayType')
        if not paywayType:
            return Response(response_message('请选择提现方式'))
        order = RecordIncomesDao().findOneByObjId(params.get('obj_id'))
        if order.orderStatus == 'REFUSE' or order.orderStatus == 'FINISH':
            return Response(response_message("该记录已处理，不可重复操作！"))
        order.__dict__.update({'orderStatus':'REFUSE', 'remark': params.get('remark'), 'outMoneyTime': datetime.datetime.now()})
        order.save()
        # 提现拒绝，归还积分
        UserDao().addWallet(paywayType, order.user, order.money)
        data = {}
        data['scene'] = 'outMoneyForRefuse'
        data['user'] = order.user.id
        data['fromUser'] = order.user.id
        data['orderId'] = ''
        data['money'] = order.money
        data['payway'] = paywayType
        data['changeWay'] = 'add'
        data['orderStatus'] = 'FINISH'
        data['remark'] = params.get('remark')
        RecordIncomesDao().create(data)

        return Response(response_success("操作成功"))
    
    
    '''商户提现确认'''
    @action(methods=['post'], detail=False)
    def confirmOutMoneyForShop(self, request):
        params = getRequestParams(request)
        order = RecordIncomesDao().findOneByObjId(params.get('obj_id'))
        if order.orderStatus == 'REFUSE' or order.orderStatus == 'FINISH':
            return Response(response_message("该记录已处理，不可重复操作！"))
        order.__dict__.update({'orderStatus': 'FINISH', 'remark': params.get('remark'), 'outMoneyTime': datetime.datetime.now()})
        order.save()

        return Response(response_success("操作成功"))

    '''积分兑换余额'''
    @action(methods=['post'], detail=False)
    def incomesToBalance(self, request):
        params = getRequestParams(request)
        _lessee = LesseeDao().getLessee()
        if request.user.isRobot:
            return Response(response_message('机器人账户不能兑换'))
        if params.get('paywayType') == 'incomes':
            if Decimal(request.user.incomes) < Decimal(params.get('payMoney')):
                return Response(response_message("兑换失败！积分不足！"))
            elif Decimal(params.get('payMoney')) < _lessee.exchangeForIncomes_min:
                return Response(response_message("兑换失败！最小兑换数量" + str(_lessee.exchangeForIncomes_min)))
            else:
                payMoney = Decimal(params.get('payMoney')).quantize(Decimal('0.00'))
                # 减少用户积分
                UserDao().subWallet('incomes', request.user, payMoney)
                data = {}
                data['scene'] = 'subToBalance'
                data['user'] = request.user.id
                data['fromUser'] = request.user.id
                data['orderId'] = ''
                data['money'] = payMoney
                data['serviceCharge'] = 0
                data['realMoney'] = payMoney
                data['payway'] = 'incomes'
                data['changeWay'] = 'sub'
                data['orderStatus'] = 'FINISH'
                RecordIncomesDao().create(data)
                # 增加用户余额
                addBalance = Decimal(payMoney/_lessee.incomesToBalanceRate).quantize(Decimal('0.00'))
                UserDao().addWallet('balance', request.user, addBalance)
                data = {}
                data['scene'] = 'incomesToBalance'
                data['user'] = request.user.id
                data['fromUser'] = request.user.id
                data['orderId'] = ''
                data['money'] = addBalance
                data['serviceCharge'] = 0
                data['realMoney'] = addBalance
                data['payway'] = 'balance'
                data['changeWay'] = 'add'
                data['orderStatus'] = 'FINISH'
                RecordIncomesDao().create(data)
        return Response(response_success("操作成功"))